package main

import (
	"fmt"
	"reflect"
	"sync"
)

type ConcurrentMap struct {
	m         sync.Map
	keyType   reflect.Type
	valueType reflect.Type
}

func NewConcurrentMap(keyType, valueType reflect.Type) (*ConcurrentMap, error) {
	if keyType == nil {
		return nil, fmt.Errorf("key 类型为 nil")
	}
	if !keyType.Comparable() { // 判断类型是否可以比较，就是是否是内做key的类型
		return nil, fmt.Errorf("不可比较的类型: %s", keyType)
	}
	if valueType == nil {
		return nil, fmt.Errorf("value 类型为 nil")
	}
	cm := &ConcurrentMap{
		keyType:   keyType,
		valueType: valueType,
	}
	return cm, nil
}

func (cm *ConcurrentMap) Load(key interface{}) (value interface{}, ok bool) {
	if reflect.TypeOf(key) != cm.keyType {
		return
	}
	return cm.m.Load(key)
}

func (cm *ConcurrentMap) Store(key, value interface{}) {
	if reflect.TypeOf(key) != cm.keyType {
		panic(fmt.Errorf("key类型不符合: 实际类型: %v, 需要类型: %v\n", reflect.TypeOf(key), cm.keyType))
	}
	if reflect.TypeOf(value) != cm.valueType {
		panic(fmt.Errorf("value类型不符合: 实际类型: %v, 需要类型: %v\n", reflect.TypeOf(value), cm.valueType))
	}
	cm.m.Store(key, value)
}

func (cm *ConcurrentMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
	if reflect.TypeOf(key) != cm.keyType {
		panic(fmt.Errorf("key类型不符合: 实际类型: %v, 需要类型: %v\n", reflect.TypeOf(key), cm.keyType))
	}
	if reflect.TypeOf(value) != cm.valueType {
		panic(fmt.Errorf("value类型不符合: 实际类型: %v, 需要类型: %v\n", reflect.TypeOf(value), cm.valueType))
	}
	actual, loaded = cm.m.LoadOrStore(key, value)
	return
}

func (cm *ConcurrentMap) Delete(key interface{}) {
	if reflect.TypeOf(key) != cm.keyType {
		return
	}
	cm.m.Delete(key)
}

func (cm *ConcurrentMap) Range(f func(key, value interface{}) bool) {
	cm.m.Range(f)
}

func main() {
	fmt.Println()
}
